﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TagBasedResourceManagePlatform;
using TagBasedResourceManagePlatform.Database;

namespace TestApp
{

    class Program
    {
        public enum OperationResult
        {
            Succeed,
            Fatal,
            Warn
        }

        public static class DatabaseOperationTest
        {
            public static OperationResult TestAddSetting()
            {
                using (var dbContext = new TagBasedResourceManagePlatform.Database.DatabaseContext())
                {
                    PrintOperation("Test add |Setting|...");
                    Setting setting = new Setting()
                    {
                        Name = Guid.NewGuid().ToString(),
                        Value = "Value-Empty"
                    };

                    try
                    {
                        dbContext.Settings.Add(setting);
                        dbContext.SaveChanges();
                    }
                    catch (Exception ex)
                    {
                        PrintResultFatal(ex);
                        return OperationResult.Fatal;
                    }
                    PrintResultSucceed();
                    return OperationResult.Succeed;
                }
            }

            public static OperationResult TestAddResource()
            {
                using (var dbContext = new TagBasedResourceManagePlatform.Database.DatabaseContext())
                {
                    PrintOperation("Test add |Resource|...");
                    Resource resource = new Resource()
                    {
                        AccessLevel = AccessLevel.Any,
                        CreateTime = DateTime.Now,
                        Description = "Null",
                        FileName="sample.sample",
                        MD5 = "32323232323",
                        MineType = new TagBasedResourceManagePlatform.Misc.MineTypeHelper.MineType("text/html"),
                        MStorageId = -1,
                        PhysicalPath = "/app.exe",
                        Ranks = 5,
                        Summary = "<Summery-Text>",
                        Title = string.Format("({0})", Guid.NewGuid().ToString()),
                        TotalViewCount = 0,
                        Type = ResourceType.File,
                        Tags = "abc,ddd,def"
                    };

                    try
                    {
                        dbContext.Resources.Add(resource);
                        dbContext.SaveChanges();
                    }
                    catch (Exception ex)
                    {
                        PrintResultFatal(ex);
                        return OperationResult.Fatal;
                    }
                    PrintResultSucceed();
                    return OperationResult.Succeed;
                }
            }

            public static OperationResult TestAddThumbnail()
            {
                using (var thumbnailDB = new TagBasedResourceManagePlatform.Database.ThumbnailDB())
                {
                    using (var dbContext = new TagBasedResourceManagePlatform.Database.DatabaseContext())
                    {
                        PrintOperation("Test add |Thumbnail|...");


                        Resource resource = (from TResource in dbContext.Resources select TResource).FirstOrDefault();
                        if (resource == null)
                        {
                            PrintResultFatal();
                            return OperationResult.Fatal;
                        }

                        System.IO.MemoryStream ms = new System.IO.MemoryStream();
                        if (!TagBasedResourceManagePlatform.Misc.ThumbnailHelper.Generate(@"C:\Users\Loysel\Pictures\123219212.jpg", ms, TagBasedResourceManagePlatform.Misc.ThumbnailHelper.PreferThumbnailSize))
                        {
                            throw new InvalidOperationException();
                        }

                        Thumbnail thumbnail = new Thumbnail()
                        {
                            Format = "image/jpeg",
                            Data = ms.GetBuffer()
                        };

                        try
                        {
                            thumbnailDB.Thumbnails.Add(thumbnail);
                            thumbnailDB.SaveChanges();
                        }
                        catch (Exception ex)
                        {
                            PrintResultFatal(ex);
                            return OperationResult.Fatal;
                        }

                        resource.ThumbnailId = thumbnail.Id;
                        try
                        {
                            dbContext.SaveChanges();
                        }
                        catch (Exception ex)
                        {
                            PrintResultFatal(ex);
                            return OperationResult.Fatal;
                        }

                        PrintResultSucceed();
                        return OperationResult.Succeed;
                    }
                }
            }

            public static OperationResult TestAddTag()
            {
                using (var dbContext = new TagBasedResourceManagePlatform.Database.DatabaseContext())
                {
                    PrintOperation("Test add |ResourceTag|...");


                    Resource resource = (from TResource in dbContext.Resources select TResource).FirstOrDefault();
                    if (resource == null)
                    {
                        PrintResultFatal();
                        return OperationResult.Fatal;
                    }

                    ResourceTag tag = new ResourceTag()
                    {
                        Resource = resource,
                        Tags = "Abc,ddd,def"
                    };

                    try
                    {
                        dbContext.ResourceTags.Add(tag);
                        dbContext.SaveChanges();
                    }
                    catch (Exception ex)
                    {
                        PrintResultFatal(ex);
                        return OperationResult.Fatal;
                    }
                    PrintResultSucceed();
                    return OperationResult.Succeed;
                }
            }

            public static OperationResult TestMatchTag()
            {
                using (var dbContext = new TagBasedResourceManagePlatform.Database.DatabaseContext())
                {
                    PrintOperation("Test Tag match operation...");

                    try
                    {
                        var tags = dbContext.Database.SqlQuery<int>("Select [ResourceId] From MAIN.[ResourceTags] WHERE ResourceTags.[Tags] match \"abc ddd\"").ToArray();

                        if (tags.Length == 0)
                        {
                            return OperationResult.Fatal;
                        }
                        var resources = from TResource in dbContext.Resources where tags.Contains(TResource.Id) select TResource;
                        foreach (var res in resources)
                        {
                            var title = res.Title + " A tilte";
                        }
                    }
                    catch (Exception ex)
                    {
                        PrintResultFatal(ex);
                        return OperationResult.Fatal;
                    }
                    PrintResultSucceed();
                    return OperationResult.Succeed;
                }
            }

            public static OperationResult TestDatabaseOperation()
            {
                if (OperationResult.Fatal == TestAddSetting())
                    return OperationResult.Fatal;

                if (OperationResult.Fatal == TestAddResource())
                    return OperationResult.Fatal;

                if (OperationResult.Fatal == TestAddThumbnail())
                    return OperationResult.Fatal;

                if (OperationResult.Fatal == TestAddTag())
                    return OperationResult.Fatal;

                if (OperationResult.Fatal == TestMatchTag())
                    return OperationResult.Fatal;

                return OperationResult.Succeed;
            }
        }

        static void Main(string[] args)
        {
            DatabaseOperationTest.TestDatabaseOperation();

            Console.ReadKey();
        }

        static void PrintOperation(string format, params object[] args)
        {
            Console.ForegroundColor = ConsoleColor.Gray;
            Console.Write(format, args);
        }

        static void PrintResultSucceed()
        {
            Console.ForegroundColor = ConsoleColor.Green;
            Console.WriteLine("Succeed");
        }

        static void PrintResultFatal(Exception ex = null)
        {
            Console.ForegroundColor = ConsoleColor.Red;
            Console.WriteLine("Fatal");

            if (ex == null) return;

            Console.WriteLine("======== Exception ========");
            Exception exception = ex;
            while (exception != null)
            {
                Console.WriteLine("Exception: {0}", exception.GetType().FullName);
                Console.WriteLine("Message: {0}", exception.Message);
                Console.WriteLine("--------");

                exception = exception.InnerException;
            }
        }

        static void PrintResultWarn()
        {
            Console.ForegroundColor = ConsoleColor.Yellow;
            Console.WriteLine("Warn");
        }
    }
}
